home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / s342q07.lha / info.c < prev    next >
C/C++ Source or Header  |  1994-10-11  |  8KB  |  355 lines

  1. /*
  2. *                Info.C
  3. *
  4. * Handles almost all aspects of the Information command of C-86
  5. */
  6. #include "ctdl.h"
  7. /*
  8. *                history
  9. *
  10. * 89Aug0? HAW    Created.
  11. */
  12. /*
  13. *                Contents
  14. *
  15. *    ReadCitInfo()        Reads info from file.
  16. *    EatInfo()        Eats an entry from file (work fn).
  17. *    CheckInfo()        Equivalency check for list.
  18. *    FreeInfo()        Frees an info structure.
  19. *    EditInfo()        Adds new information.
  20. *    GetInfo()        Get information for a room.
  21. *    doInfo()        Dump info on room.
  22. *    WriteOutInformation()    Writes information to disk.
  23. *    KillInfo()        Kills info of dead room.
  24. *    ChangeInfoName()    Called for room name change.
  25. *    AllInfo()        .Known Info.
  26. *    InfoShow()        work fn to show information.
  27. *    WriteNewInfo()        Writes entry to disk.
  28. */
  29. #define ROOM_HEADER    "#room"
  30. extern CONFIG  cfg;
  31. extern struct floor  *FloorTab;
  32. extern rTable    *roomTab;
  33. extern MessageBuffer msgBuf;
  34. extern logBuffer logBuf;
  35. extern aRoom   roomBuf;        /* Room buffer            */
  36. extern char    haveCarrier;    /* Have carrier?        */
  37. extern char    onConsole;    /* How about on Console?    */
  38. extern char    outFlag;        /* Output flag            */
  39. /*
  40. * Data Format
  41. *
  42. * All room information is kept in a single file named ctdlinfo.sys.  It's
  43. * straight text, in which each record begins with a line that looks like
  44. *
  45. *    #room <roomname>
  46. *
  47. * and ends with a completely blank line (a space on that line will make it
  48. * non-blank, thus allowing blank lines to separate paragraphs in long
  49. * information entries).
  50. *
  51. * As a later note, this format is inadequate.  Direct editing of this file
  52. * can throw away those blank spots.  A better record ending convention, such
  53. * as a line that says simply '#end', would probably be for the best.  Maybe
  54. * do that in the next major release.
  55. */
  56. typedef struct
  57.   {
  58.   label Roomname;
  59.   char  *Info;
  60.  
  61.   }
  62. RoomInfo;
  63. static void *EatInfo(char *line);
  64. void *CheckInfo(RoomInfo *d1, RoomInfo *d2);
  65. static void FreeInfo(RoomInfo *d);
  66. char *GetInfo(label name);
  67. static int InfoShow(int r);
  68. static SListBase InfoList =
  69.   {
  70.   NULL, CheckInfo, NULL, FreeInfo, EatInfo
  71.  
  72.   };
  73. static FILE *fd;
  74. /*
  75. * ReadCitInfo()
  76. *
  77. * This function will read in the C-86 room info file.
  78. */
  79. void ReadCitInfo()
  80.   {
  81.   SYS_FILE fn;
  82.   makeSysName(fn, "ctdlinfo.sys", &cfg.roomArea);
  83.   if ((fd = safeopen(fn, "r")) != NULL)
  84.     {
  85.     MakeList(&InfoList, "", fd);
  86.     fclose(fd);
  87.  
  88.     }
  89.  
  90.   }
  91. /*
  92. * EatInfo()
  93. *
  94. * This eats some info from the information file.  This function is a bit
  95. * non-obvious because it is called from the generic MakeList() function,
  96. * which generally expects one record/per line format.  Therefore, we have
  97. * to cheat a bit in order to read in the extra lines and still return a
  98. * meaningful record.
  99. *
  100. * Basically, if the line sent in is not the beginning of a room info entry,
  101. * NULL is returned.  Otherwise, we cheat by reading in the rest of the
  102. * entry from the global FILE pointer and return the entire record.
  103. */
  104. static void *EatInfo(char *line)
  105.   {
  106.   RoomInfo *temp;
  107.   char     *c;
  108.   if (strncmp(line, ROOM_HEADER, strLen(ROOM_HEADER)) != SAMESTRING)return NULL;
  109.   temp = GetDynamic(sizeof *temp);
  110.   strCpy(temp->Roomname, line + 1 + strLen(ROOM_HEADER));
  111.   msgBuf.mbtext[0] = 0;
  112.   c = msgBuf.mbtext;
  113.   while (fgets(c, 100, fd) != NULL && *c != '\n')
  114.     {
  115.     c = lbyte(msgBuf.mbtext);
  116.  
  117.     };
  118.   temp->Info = strdup(msgBuf.mbtext);
  119.   return temp;
  120.  
  121.   }
  122. /*
  123. * CheckInfo()
  124. *
  125. * This function checks to see if two infos reference the same room.
  126. */
  127. void *CheckInfo(RoomInfo *d1, RoomInfo *d2)
  128.   {
  129.   return ((strCmpU(d1->Roomname, d2->Roomname)
  130.   != SAMESTRING) ? NULL : d1);
  131.  
  132.   }
  133. /*
  134. * FreeInfo()
  135. *
  136. * This function will free an info structure.
  137. */
  138. static void FreeInfo(RoomInfo *d)
  139.   {
  140.   free(d->Info);
  141.   free(d);
  142.  
  143.   }
  144. /*
  145. * EditInfo()
  146. *
  147. * This function adds new information.  Once the new information is acquired
  148. * the entire list is written back out to disk.
  149. */
  150. void EditInfo()
  151.   {
  152.   RoomInfo *d;
  153.   char *c;
  154.   extern char MsgEntryType, EndWithCR;
  155.   d = GetDynamic(sizeof *d);
  156.   strCpy(d->Roomname, roomBuf.rbname);
  157.   if ((c = GetInfo(roomBuf.rbname)) != NULL)
  158.     {
  159.     if (getYesNo("EDCURI"))
  160.     strCpy(msgBuf.mbtext, c);
  161.     else
  162.     msgBuf.mbtext[0] = 0;
  163.  
  164.     }
  165.   else msgBuf.mbtext[0] = 0;
  166.   MsgEntryType = INFO_ENTRY;
  167.   Output_Citadel_Message("INFOED",NULL, NULL, NULL);
  168.   doCR();
  169.   CleanEnd(msgBuf.mbtext);
  170.   mPrintf("%s", msgBuf.mbtext);
  171.   outFlag = OUTOK;
  172.   if (GetBalance(ASCII, msgBuf.mbtext, MAXTEXT-50) && onLine())
  173.     {
  174.     CleanEnd(msgBuf.mbtext);
  175.     d->Info = strdup(msgBuf.mbtext);
  176.     if (c != NULL || strLen(msgBuf.mbtext) != 0)
  177.       {
  178.       AddData(&InfoList, d, NULL, TRUE);
  179.       WriteOutInformation();
  180.  
  181.       }
  182.     else free(d);
  183.  
  184.     }
  185.  
  186.   }
  187. /*
  188. * GetInfo()
  189. *
  190. * This function will get the information for a given room.
  191. */
  192. char *GetInfo(label name)
  193.   {
  194.   char *result;
  195.   RoomInfo d, *c;
  196.   strCpy(d.Roomname, name);
  197.   result =  (c = SearchList(&InfoList, &d)) == NULL ? NULL : c->Info;
  198.   return result;
  199.  
  200.   }
  201. /*
  202. * doInfo()
  203. *
  204. * This function dumps info on current room.
  205. */
  206. char doInfo()
  207.   {
  208.   char *c;
  209.   extern char journalMessage;
  210.   mPrintf("\n \n ");
  211.   if ((c = GetInfo(roomBuf.rbname)) != NULL)
  212.     {
  213.     mPrintf("%s", c);
  214.     doCR();
  215.     if (journalMessage)
  216.       {
  217.       if (redirect(NULL))
  218.         {
  219.         mPrintf("%s", c);
  220.         doCR();
  221.         undirect();
  222.  
  223.         }
  224.       journalMessage = FALSE;
  225.  
  226.       }
  227.  
  228.     }
  229.   else Output_Citadel_Message("NOINFO",(long)roomBuf.rbname,NULL, NULL);
  230.   return GOOD_SELECT;
  231.  
  232.   }
  233. /*
  234. * WriteOutInformation()
  235. *
  236. * This function writes out information to disk.
  237. */
  238. void WriteOutInformation()
  239.   {
  240.   void WriteNewInfo();
  241.   SYS_FILE fn;
  242.   makeSysName(fn, "ctdlinfo.sys", &cfg.roomArea);
  243.   fd = safeopen(fn, "w");
  244.   RunList(&InfoList, WriteNewInfo);
  245.   fclose(fd);
  246.  
  247.   }
  248. /*
  249. * KillInfo()
  250. *
  251. * This function kills some info.  This is used when a room is killed.
  252. */
  253. void KillInfo(char *name)
  254.   {
  255.   RoomInfo d;
  256.   if (GetInfo(name) != NULL)
  257.     {
  258.     strCpy(d.Roomname, name);
  259.     KillData(&InfoList, &d);
  260.     WriteOutInformation();
  261.  
  262.     }
  263.  
  264.   }
  265. /*
  266. * ChangeInfoName()
  267. *
  268. * This function is called when a room name is changed.
  269. */
  270. void ChangeInfoName(char *newname)
  271.   {
  272.   RoomInfo d, *c;
  273.   strCpy(d.Roomname, roomBuf.rbname);
  274.   if ((c = SearchList(&InfoList, &d)) != NULL)
  275.     {
  276.     strCpy(c->Roomname, newname);
  277.     WriteOutInformation();
  278.  
  279.     }
  280.  
  281.   }
  282. /*
  283. * AllInfo()
  284. *
  285. * This function implements .Known Info.
  286. */
  287. void AllInfo()
  288.   {
  289.   int rover, roomNo;
  290.   extern int TopFloor;
  291.   extern char ShowNew, SelNew;
  292.   doCR();
  293.   if (FloorMode)
  294.     {
  295.     for (rover = 0; rover < TopFloor; rover++)
  296.       {
  297.       roomNo = FirstRoom(rover);
  298.       ShowNew = 2;
  299.       SelNew = TRUE;
  300.       if (FloorRunner(roomNo, CheckFloor) != ERROR)
  301.         {
  302.         mPrintf("[%s]", FloorTab[rover].FlName);
  303.         doCR();
  304.         FloorRunner(roomNo, InfoShow);
  305.  
  306.         }
  307.       ShowNew = FALSE;
  308.       SelNew = FALSE;
  309.  
  310.       }
  311.  
  312.     }
  313.   else tableRunner(InfoShow, TRUE);
  314.  
  315.   }
  316. /*
  317. * InfoShow()
  318. *
  319. * This function will actually show the information for a room.
  320. */
  321. static int InfoShow(int r)
  322.   {
  323.   char *c;
  324.   int  rover;
  325.   extern int DirAlign;
  326.   extern char AlignChar;
  327.   if ((c = GetInfo(roomTab[r].rtname)) != NULL) CleanEnd(c);
  328.   if (c != NULL && strLen(c) != 0)
  329.     {
  330.     mPrintf("%s ", roomTab[r].rtname);
  331.     for (rover = strLen(roomTab[r].rtname); rover < 22; rover++)
  332.     oChar('.');
  333.     oChar(' ');
  334.     DirAlign = 22;
  335.     AlignChar = ' ';
  336.     mPrintf("%s", c);
  337.     DirAlign = 0;
  338.     doCR();
  339.  
  340.     }
  341.   return 0;
  342.  
  343.   }
  344. /*
  345. * WriteNewInfo()
  346. *
  347. * This function will write out a chunk of new information.
  348. */
  349. void WriteNewInfo(RoomInfo *d)
  350.   {
  351.   CleanEnd(d->Info);
  352.   fprintf(fd, "#room %s\n%s\n\n", d->Roomname, d->Info);
  353.  
  354.   }
  355.